/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package frmsystem;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 *
 * @author bahria
 */
public class Domain implements IDomain {

	protected static IDomain instance;
    protected ICreator creator;
    protected List<IAccount> accounts = new ArrayList<IAccount>();
    protected List<IParty> parties = new ArrayList<IParty>();
    
    public Domain(){
    	creator = new Creator();
    }

    public static IDomain getInstance() {
    	if(instance==null){
    		instance = new Domain();
    	}
		return instance;
	}

	@Override
	public void applyInterest() {
		for(IAccount acc : accounts){
			acc.applyInterest();
		}
		
	}

	@Override
	public void doTransaction(String name, String accNo, int transactionType, double amount) {			
		IAccount acc = searchAccount(accNo);
		IParty party = getParty(name);
		if(acc!=null){
			IEntry entry = creator.createTransaction(party, acc, transactionType, amount);
			acc.executeTransaction(entry);
		}
	}

	@Override
	public String generateReport() {
		String result = "";
		for(IAccount acc : accounts){
			
			result += "Account # " + acc.getAccountNo() + "\n";
			result += acc.getReportAll();
			result += "------------------------\n";			
		}
		
		return result;
		
	}

	@Override
	public void registerOrganization(String name, String street, String city,
			String state, String zip, String email, int noOfEmp, int accType, String accNo) {
		IParty party = getParty(name);
		if(party==null){
			party = creator.createOrganization(name, street, city, state, zip, email, noOfEmp);
			if(accNo==null)
				accNo = UUID.randomUUID().toString();
			IAccount account = creator.createAccount(accNo, accType);
			party.openAccount(account);
			account.addObserver(party);
			this.parties.add(party);
			this.accounts.add(account);
		}else{
			if(accNo==null)
				accNo = UUID.randomUUID().toString();
			IAccount account = creator.createAccount(accNo, accType);
			party.openAccount(account);
			account.addObserver(party);
			this.accounts.add(account);
		}
		
	}

	@Override
	public void registerPerson(String name, String street, String city,
			String state, String zip, String email, String birthDate, int accType, String accNo) {
		IParty party = getParty(name);
		if(party==null){
			party = creator.createPerson(name, street, city, state, zip, email, birthDate);
			if(accNo==null){
				accNo = UUID.randomUUID().toString();
			}
			IAccount account = creator.createAccount(accNo, accType);
			party.openAccount(account);
			account.addObserver(party);
			this.parties.add(party);
			this.accounts.add(account);	
		}else{
			if(accNo==null){
				accNo = UUID.randomUUID().toString();
			}
			IAccount account = creator.createAccount(accNo, accType);
			party.openAccount(account);
			account.addObserver(party);
			this.accounts.add(account);	
		}
	}
	
	public IAccount searchAccount(String accNo){
		for(IAccount acc: accounts){
			if(accNo.equals(acc.getAccountNo())){
				return acc;
			}
		}
		
		return null;
	}

	@Override
	public String[][] getAccountData() {
		return new String[][]{{"sfsdfd", "james", "iowa"}, {"werer", "kelvin", "iowa"}};
	}

	@Override
	public String[] getTitles() {
		return new String[]{"Account No", "Name", "State"};
	}
	
	protected IParty getParty(String name){
		for(IParty party : parties){
			if(party.getName().equals(name)){
				return party;
			}
		}
		
		return null;
	}

	@Override
	public String generateReport(String accNo) {
		String result = "";
		if(accNo!=null || !"".equals(accNo)){
			IAccount acc = searchAccount(accNo);
			result += "Account # " + acc.getAccountNo() + "\n";
			result += acc.getReportAll();
			result += "------------------------\n";	
		}
		
		return result;
	}

}
